/*
 * Serve de suporte para leitura e escrita em ficheiros
 */

package protocol;
import core.Callback;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Tiago
 */
public class TSFile {

    private TSFileTag fileTag;

    private List<byte []> buffer= new LinkedList<byte[]>();

    private static final int MAX_BUFFER = 1024;

    private boolean isOpen = false;
    
    private FileChannel channel;

    private FileOutputStream fileOutputStream;

    private String name;

    private RandomAccessFile rfile;


    private Callback callback;
    /**
     *
     * Modo de leitura
     *
     * @param fileTag
     * @throws FileNotFoundException
     */
    public TSFile(TSFileTag fileTag) throws FileNotFoundException {
        this.fileTag = fileTag;
        name = fileTag.getKey()+"";
        rfile = new RandomAccessFile(name,"r");
    }

    public void setCallback(Callback callback) {
        this.callback = callback;
    }

    public Callback getCallback() {
        return callback;
    }


    

    public RandomAccessFile getRfile() {
        return rfile;
    }



    /**
     * Abre um ficheiro temporário
     *
     * nome do ficheiro key:ticket
     * @throws FileNotFoundException
     */
    public TSFile(int key,int ticket,int size) throws FileNotFoundException, IOException {
        name = key+"."+ticket;
        File file= new File(".//"+name);
        
//        if(file.exists())
//            file.delete();
//        file.createNewFile();
        fileOutputStream = new FileOutputStream(file,false);
        fileTag = new TSFileTag(key, size);
    }


    /**
     * Abre um ficheiro e preenche toda a informação do TSFileTag
     *
     * Modo de leitura
     * 
     * @throws FileNotFoundException
     */
    public TSFile(int key) throws FileNotFoundException, IOException {
        rfile = new RandomAccessFile(key+"","rws");
        fileTag = new TSFileTag(key, new Long(rfile.length()).intValue());
    }

    public TSFileTag getFileTag() {
        return fileTag;
    }

    public String getName() {
        return name;
    }

    public FileOutputStream getFileOutputStream() {
        return fileOutputStream;
    }

    


    public boolean isEmpty(){
        return buffer.size()==0;
    }


    public synchronized boolean openFile() throws IOException{
        
        isOpen = true;
        return true;
    }

    public synchronized void close(){
        try {
            fileOutputStream.flush();
            fileOutputStream.close();

        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public synchronized boolean delete(){
        close();
        File f = new File(fileTag.getKey()+"");
        
        return f.delete();
    }

    public boolean isOpen(){
         return fileOutputStream==null?false:fileOutputStream.getChannel()==null?false:fileOutputStream.getChannel().isOpen();
        
    }

    public void write(byte[] data){
        synchronized(buffer){
            buffer.add(data);
        }
    }

    public FileChannel getReadChannel() throws IOException {
       synchronized(rfile){
          if(channel==null){
            channel = rfile.getChannel();
          }
       }
       return channel;
    }

   

    public List<byte[]> removeBuffer(){
        synchronized(buffer){
            List<byte[]> list = new ArrayList<byte[]>(buffer);
            buffer.clear();
            return list;
        }
    }
}
